#include "Server.hpp"


std::unordered_map<uint64_t, ConnPtr> _connections;
uint64_t conn_id = 0;


//到时候，TcpServer是使用主从Reactor模型
//主线程进行连接获取并派发，然后分配eventloop线程！
//这里没有用线程池，我们就先用一个全局变量来做！
EventLoop base_loop;   //这个是给主线程进行收取连接的！

std::vector<ThreadLoop> threads(2);
int next_loop = 0;

//这里为了方便测试，我们手动地为普通套接字的回调编写一下！
void HandlerClose(ConnPtr conn){
//关闭套接字的回调：不仅仅是关闭连接，还要先取消关注！
    std::cout << "close the fd : " << conn->Fd() << std::endl;
    //取消关注
    conn->ConnChannel()->DelWriteEventMonitor();
    close(conn->Fd());
}

void OnConnected(ConnPtr conn){
    LOG(LogLevel::DEBUG) << "NEW CONNECTION : %s" << conn.get();
}

void OnMessage(ConnPtr conn, Buffer* buf){
    std::string s = buf->ReadAsString(buf->ReadableSize());
    LOG(LogLevel::DEBUG) << s;
    std::string ret = s + " : hello world";
    conn->Send((char*)ret.c_str(), ret.size());
}

void OnClose(ConnPtr conn){
    LOG(LogLevel::DEBUG) << "CLOSE : " << conn->Fd();
}

void OnAny(ConnPtr conn){
    LOG(LogLevel::DEBUG) << "Any : " << conn->Fd();
}

void DelConn(ConnPtr conn){
    _connections.erase(conn->Id());
}

//这一次，这接口就变成了：当Acceptor获取到新的连接时，需要执行回调->其实就是对新连接进行一些设置！
void AcceptCallback(int fd){
    //开始设置新连接,这一次的连接就变成了Connection
    next_loop = (next_loop + 1) % 2;
    ConnPtr conn = std::make_shared<Connection>(threads[next_loop].GetLoop(), ++conn_id, fd);
    conn->SetMessageCallback(std::bind(OnMessage, std::placeholders::_1, std::placeholders::_2));
    conn->SetConnectedCallback(std::bind(OnConnected, std::placeholders::_1));
    //conn->SetClosedCallback(std::bind(OnClose, conn));
    //conn->SetAnyEventCallback(std::bind(OnAny, conn));
    

    //设置真正的对上层连接进行释放的接口
    conn->SetServerClosedCallback(std::bind(DelConn, std::placeholders::_1));
    //启动非活跃
    conn->EnableInactiveRelease(2); //设定超时时间10s
    //设置就绪状态
    conn->Establish();
    //将当前连接加入到哈希
    _connections[conn_id] = conn;
}


// ./test_svr.exe server_port
int main(int argc, char* argv[]){
    if(argc != 2) return -1;

    srand((unsigned int)time(nullptr));

    //这里是端口号
    uint16_t server_port = std::stoi(argv[1]);

    Acceptor ac(&base_loop, server_port);
    ac.SetAcceptCallback(std::bind(AcceptCallback, std::placeholders::_1));
    ac.StartListen();

    while(1){
        base_loop.Start();
        std::cout << "当前被管理的连接:" << std::endl;
        for(auto& it : _connections){
            std::cout << it.first << " ";
        }
        std::cout << std::endl;
    }
    return 0;
}